using FileServer.Abstractions;
using FileServer.Abstractions.Models.Entities;
using SqlSugar;
using System.IO;

namespace FileServer.Storage.MySql;

/// <summary>
/// mysql  仓储实现类
/// </summary>
public class MysqlFileStorage : IFileStorage
{
    private readonly MySqlSugarContext _context;
    public SqlSugarScope Db { get; }

    public MysqlFileStorage(MySqlSugarContext context)
    {
        _context = context;
        Db = _context.Scope;
    }

    public async Task ExecuteCommand(string sql)
    {
        await Db.Ado.ExecuteCommandAsync(sql);
    }

    public async Task<List<FileResource>> GetByIds(List<string> ids)
    {
        return await Db.Queryable<FileResource>().Where(x => ids.Contains(x.Id)).ToListAsync();
    }

    public async Task<FileResource> Get(string id)
    {
        return await Db.Queryable<FileResource>().Where(x => x.Id.Equals(id)).FirstAsync();
    }

    public async Task<FileResource> GetByPath(string path)
    {
        return await Db.Queryable<FileResource>().Where(x => x.Path.Equals(path)).FirstAsync();
    }


    public async Task<bool> Add(FileResource resource)
    {
        if (string.IsNullOrEmpty(resource.Id))
        {
            resource.Id = Guid.NewGuid().ToString().Replace("-", "");
        }
        var count = await Db.Insertable<FileResource>(resource).ExecuteCommandAsync();
        return count > 0;
    }



    public async Task<bool> Delete(string fileUrl)
    {
        var resource = await GetByPath(fileUrl);
        if (resource == null)
        {
            return false;
        }

        await Db.Deleteable<FileResource>(resource.Id).ExecuteCommandAsync();
        return true;
    }

    public async Task<bool> SaveTemp(string path)
    {
        var resource = await GetByPath(path);
        if (resource == null)
        {
            return false;
        }
        resource.IsTemp = false;
        return await Db.Updateable<FileResource>(resource).ExecuteCommandAsync() > 0;
    }

    public async Task<bool> SaveTemp(List<string> paths)
    {
        var resources = await Db.Queryable<FileResource>().Where(x => paths.Contains(x.Path)).ToListAsync();
        if (resources?.Count <= 0)
        {
            return false;
        }

        foreach (var resource in resources)
        {
            resource.IsTemp = false;
        }
        return await Db.Updateable(resources).ExecuteCommandAsync() > 0;
    }

    public async Task<bool> DeleteById(string id)
    {
        await Db.Deleteable<FileResource>(id).ExecuteCommandAsync();
        return true;
    }

    public async Task<(int total, List<FileResource> list)> GetPageList(string fileName, string startTime, string endTime, string fileUrl, string fileNo, string fileId, int page, int size)
    {
        RefAsync<int> total = 0;
        var list = await Db.Queryable<FileResource>().WhereIF(!string.IsNullOrEmpty(fileName), x => x.OriginName.Equals(fileName))
             .WhereIF(!string.IsNullOrEmpty(fileNo), x => x.FileNo.Equals(fileNo))
             .WhereIF(!string.IsNullOrEmpty(fileUrl), x => x.Path.Equals(fileUrl))
              .WhereIF(!string.IsNullOrEmpty(startTime), x => x.CreateTime >= (DateTime.Parse(startTime)))
              .WhereIF(!string.IsNullOrEmpty(endTime), x => x.CreateTime <= (DateTime.Parse(endTime)))
               .WhereIF(!string.IsNullOrEmpty(fileId), x => x.Id.Equals(fileId))
               .OrderByDescending(x=>x.CreateTime)
               .ToOffsetPageAsync(page, size, total);
        return (total, list);
    }
}